package com.easydisk.file.controller;

import com.easydisk.common.util.StringListUtil;
import com.easydisk.file.model.req.*;
import com.easydisk.file.model.vo.*;
import com.easydisk.file.service.UploadFileService;
import com.easydisk.file.service.UserFileService;
import com.easydisk.model.req.AddRootFolderReq;
import com.easydisk.response.ApiResponse;
import com.easydisk.common.util.SecurityContextUtil;
import com.easydisk.common.util.UserIdUtil;
import com.easydisk.vo.UserFileParam;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotNull;
import java.io.IOException;
import java.util.List;

/**
 * @author word
 */
@RestController
@RequestMapping("/file")
public class FileController {


    @Autowired
    private UserFileService userFileService;

    @Autowired
    private UploadFileService uploadFileService;



    /**
     *  根据文件Id和用户id找到userFile信息
     */
    @GetMapping("/get/info/param")
    public ApiResponse<UserFileParam> getUserFileParam(@RequestParam Long fileId,
                                                       @RequestParam Long userId) {
        UserFileParam userFileParam = userFileService.getUserFileParam(fileId, userId);
        return ApiResponse.data(userFileParam);
    }

    /**
     * 预览单个文件
     *
     * @param fileId
     * @return
     */
    @ApiOperation(
            value = "预览单个文件",
            notes = "该接口提供了预览单个文件的功能"
    )
    @GetMapping("preview")
    public void preview(@NotNull(message = "文件id不能为空")
                            @RequestParam(value = "fileId", required = false) Long fileId,
                        HttpServletResponse response) {
        userFileService.preview(fileId, response, SecurityContextUtil.getUserId());
    }

    /**
     * 获取文件列表
     *
     */
    @GetMapping("/list")
    public ApiResponse<List<UserFileVO>> list(@NotNull(message = "父id不能为空") @RequestParam(value = "parentId", required = false ) Long parentId,
                                                 @RequestParam(name = "fileTypes", required = false, defaultValue = "-1") String fileTypes) {
        // 获取当前登录用户Id,从ThreadLocal获取
        Long userId = SecurityContextUtil.getUserId();
        List<UserFileVO> list = userFileService.getUserFileList(parentId, fileTypes, userId);
        return ApiResponse.data(list);
    }


    /**
     * 获取文件夹树
     *
     */
    @GetMapping("/folder/tree")
    public ApiResponse<List<FolderTreeVO>> getFolderTree() {
        Long userId = SecurityContextUtil.getUserId();
        List<FolderTreeVO> folderTree = userFileService.getFolderTree(userId);
        return ApiResponse.success(null, folderTree);
    }


    /**
     * 新建文件夹
     *
     */
    @PostMapping("/add/folder")
    public ApiResponse<String> addFolder(@Validated @RequestBody AddFolderReq addFolderReq) {
        Long userId = SecurityContextUtil.getUserId();
        userFileService.addFolder(addFolderReq.getParentId(), addFolderReq.getFolderName(), userId);
        return ApiResponse.success();
    }
    /**
     * 新建root文件夹
     *
     */
    @PostMapping("/add/folder/root")
    public ApiResponse<String> addFolder(@Validated @RequestBody AddRootFolderReq addRootFolderReq) {
        userFileService.addFolder(addRootFolderReq.getParentId(), addRootFolderReq.getFolderName(), addRootFolderReq.getUserId());
        return ApiResponse.success();
    }

    /**
     * 文件重命名
     *
     */
    @PutMapping("/rename")
    public ApiResponse<String> updateFilename(@Validated @RequestBody UpdateFileNameReq updateFileNameReq) {
        Long userId = SecurityContextUtil.getUserId();

        userFileService.updateFilename(updateFileNameReq.getFileId(), updateFileNameReq.getNewFilename(), userId);
        return ApiResponse.success();
    }

    /**
     * 删除文件(批量)
     *
     */
    @DeleteMapping("/batch/delete")
    public ApiResponse<String> deleteByIds(@Validated @RequestBody DelFileIdsReq delFileIdsReq) {
        Long userId = SecurityContextUtil.getUserId();
        userFileService.deleteByIds(StringListUtil.string2LongList(delFileIdsReq.getFileIds()), userId);
        return ApiResponse.success();
    }



    /**
     * 查询文件详情
     *
     * @param fileId
     * @return
     */
    @GetMapping("/get/info")
    public ApiResponse<UserFileVO> getUserFileInfo(@RequestParam(value = "fileId", required = false) Long fileId) {
        Long userId = SecurityContextUtil.getUserId();
        UserFileVO userFileVO = userFileService.getNotParentUserFileInfo(fileId, userId);
        return ApiResponse.success("请求成功！", userFileVO);

    }

    /**
     * 上传单文件
     *
     */
    @PostMapping("/upload")
    public ApiResponse<String> uploadFile(@Validated UploadFileReq uploadFileReq) {
        Long userId = SecurityContextUtil.getUserId();
        uploadFileService.uploadFile(uploadFileReq.getFile(),
                uploadFileReq.getParentId(), userId,
                uploadFileReq.getIdentifier(), uploadFileReq.getTotalSize(), uploadFileReq.getFilename());
        return ApiResponse.success();
    }

    /**
     * 检查已上传的分片
     *
     */
    @GetMapping("/chunk-upload")
    public ApiResponse<CheckFileChunkUploadVO> checkUploadWithChunk(@Validated FileChunkCheckReq fileChunkCheckReq) throws IOException {

        // 获取当前登录用户id
        Long userId = SecurityContextUtil.getUserId();
        CheckFileChunkUploadVO checkFileChunkUploadVO =
                uploadFileService.checkUploadWithChunkByRedis(userId, fileChunkCheckReq);
        return ApiResponse.success(null,checkFileChunkUploadVO);
    }


    /**
     * 分片上传文件
     *
     * @return
     */
    @PostMapping("/chunk-upload")
    public ApiResponse<FileChunkUploadVO> uploadWithChunk(@Validated FileChunkUploadReq fileChunkUploadReq) {
        Long userId = SecurityContextUtil.getUserId();
        FileChunkUploadVO fileChunkUploadVO = uploadFileService.uploadWithChunkByRedis(
                fileChunkUploadReq.getFile(),
                userId,
                fileChunkUploadReq.getIdentifier(),
                fileChunkUploadReq.getTotalChunks(),
                fileChunkUploadReq.getChunkNumber(),
                fileChunkUploadReq.getTotalSize(),
                fileChunkUploadReq.getFilename());
        return ApiResponse.success(null, fileChunkUploadVO);
    }
    /**
     * 合并文件分片
     *
     */
    @PostMapping("/merge")
    public ApiResponse<String> mergeFileChunks(@Validated @RequestBody FileChunkMergeReq fileChunkMergeReq) {
        Long userId = SecurityContextUtil.getUserId();
        uploadFileService.mergeFileChunksByRedis(fileChunkMergeReq.getFilename(), fileChunkMergeReq.getIdentifier(),
                fileChunkMergeReq.getParentId(), fileChunkMergeReq.getTotalSize(),userId);
        return ApiResponse.success();
    }

    /**
     * 秒传文件
     */

    @PostMapping("/sec-upload")
    public ApiResponse<String> secUpload(@Validated @RequestBody FileSecUploadReq fileSecUploadReq) {

        Long userId = SecurityContextUtil.getUserId();
        boolean success = userFileService.secondUploadFile(fileSecUploadReq.getParentId(), fileSecUploadReq.getFilename(), fileSecUploadReq.getIdentifier(), userId);
        if (success) {
            return ApiResponse.success();
        }
        return ApiResponse.fail("文件唯一标识不存在，请执行物理上传");
    }

    /**
     * 下载文件(只支持单个下载)
     *
     */
    @GetMapping("/download")
    public void downloadFile(@NotNull(message = "请选择要下载的文件")
                             @RequestParam(value = "fileId", required = false) Long fileId,
                         HttpServletResponse response) {
        Long userId = SecurityContextUtil.getUserId();
        uploadFileService.downloadFile(fileId, response, userId);
    }

    /**
     * 转移文件(批量)
     */
    @PostMapping("/batch/transfer")
    public ApiResponse<String> transferFile(@Validated @RequestBody TransferFilesReq transferFilesReq) {
        Long userId = SecurityContextUtil.getUserId();
        UserIdUtil.get();
        userFileService.transferFiles(transferFilesReq.getFileIds(), transferFilesReq.getTargetParentId(), userId);
        return ApiResponse.success();
    }

    /**
     * 复制文件(批量)
     */
    @PostMapping("/batch/copy")
    public ApiResponse<String> copyFile(@Validated @RequestBody CopyFileReq copyFileReq) {
        Long userId = SecurityContextUtil.getUserId();
        userFileService.copyFiles(copyFileReq.getFileIds(), copyFileReq.getTargetParentId(), userId);
        return ApiResponse.success();
    }

    /**
     * 通过文件名搜索文件列表
     *
     */
    @GetMapping("/search")
    public ApiResponse<List<UserFileSearchVO>> search(@RequestParam(value = "keyword", required = false) String keyword,
                                                      @RequestParam(name = "fileTypes", required = false, defaultValue = "-1") String fileTypes) {

        if(StringUtils.isBlank(keyword)){
            return ApiResponse.fail("请输入搜索内容");
        }
        Long userId = SecurityContextUtil.getUserId();
        List<UserFileSearchVO> search = userFileService.search(keyword, fileTypes, userId);
        return ApiResponse.success(null, search);
    }

    /**
     * 获取面包屑列表
     *
     * @return
     */
    @ApiOperation(
            value = "获取面包屑列表",
            notes = "该接口提供了获取面包屑列表的功能",
            consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
            produces = MediaType.APPLICATION_JSON_UTF8_VALUE
    )
    @GetMapping("/breadcrumbs")
    public ApiResponse<List<BreadcrumbVO>> getBreadcrumbs(@NotNull(message = "文件id不能为空") @RequestParam(value = "fileId", required = false) Long fileId) {
        Long userId = SecurityContextUtil.getUserId();
        return ApiResponse.data(userFileService.getBreadcrumbs(fileId, userId));
    }


}